package com.cencat.order.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cencat.order.entity.Dispatch;
import com.cencat.order.vo.DispatchVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 智能派单数据访问层接口
 * 
 * @author cencat
 * @date 2024-01-20
 */
@Mapper
public interface DispatchMapper extends BaseMapper<Dispatch> {

    /**
     * 分页查询派单列表
     *
     * @param page 分页参数
     * @param dispatchCode 派单编号(模糊查询)
     * @param orderCode 订单编号(模糊查询)
     * @param driverCode 司机编号(模糊查询)
     * @param dispatchType 派单类型
     * @param dispatchMethod 派单方式
     * @param dispatchStatus 派单状态
     * @param priority 优先级
     * @param urgencyLevel 紧急程度
     * @param startTime 创建开始时间
     * @param endTime 创建结束时间
     * @return 派单分页列表
     */
    IPage<DispatchVO> selectDispatchPage(Page<DispatchVO> page,
                                       @Param("dispatchCode") String dispatchCode,
                                       @Param("orderCode") String orderCode,
                                       @Param("driverCode") String driverCode,
                                       @Param("dispatchType") String dispatchType,
                                       @Param("dispatchMethod") String dispatchMethod,
                                       @Param("dispatchStatus") Integer dispatchStatus,
                                       @Param("priority") Integer priority,
                                       @Param("urgencyLevel") Integer urgencyLevel,
                                       @Param("startTime") LocalDateTime startTime,
                                       @Param("endTime") LocalDateTime endTime);

    /**
     * 根据派单编号查询派单信息
     *
     * @param dispatchCode 派单编号
     * @return 派单信息
     */
    DispatchVO selectByDispatchCode(@Param("dispatchCode") String dispatchCode);

    /**
     * 根据订单编号查询派单信息
     *
     * @param orderCode 订单编号
     * @return 派单信息列表
     */
    List<DispatchVO> selectByOrderCode(@Param("orderCode") String orderCode);

    /**
     * 根据司机编号查询派单信息
     *
     * @param driverCode 司机编号
     * @param dispatchStatus 派单状态
     * @param startTime 查询开始时间
     * @param endTime 查询结束时间
     * @return 派单信息列表
     */
    List<DispatchVO> selectByDriverCode(@Param("driverCode") String driverCode,
                                      @Param("dispatchStatus") Integer dispatchStatus,
                                      @Param("startTime") LocalDateTime startTime,
                                      @Param("endTime") LocalDateTime endTime);

    /**
     * 查询待派单的订单
     *
     * @param priority 优先级
     * @param urgencyLevel 紧急程度
     * @param dispatchType 派单类型
     * @param limit 查询数量限制
     * @return 待派单订单列表
     */
    List<DispatchVO> selectPendingDispatches(@Param("priority") Integer priority,
                                           @Param("urgencyLevel") Integer urgencyLevel,
                                           @Param("dispatchType") String dispatchType,
                                           @Param("limit") Integer limit);

    /**
     * 查询智能派单候选司机
     *
     * @param pickupLongitude 取货点经度
     * @param pickupLatitude 取货点纬度
     * @param deliveryLongitude 配送点经度
     * @param deliveryLatitude 配送点纬度
     * @param vehicleType 车辆类型要求
     * @param loadCapacity 载重要求
     * @param volumeCapacity 体积要求
     * @param timeWindow 时间窗口
     * @param radius 搜索半径(公里)
     * @param limit 候选司机数量限制
     * @return 候选司机列表
     */
    List<Map<String, Object>> selectCandidateDrivers(@Param("pickupLongitude") BigDecimal pickupLongitude,
                                                    @Param("pickupLatitude") BigDecimal pickupLatitude,
                                                    @Param("deliveryLongitude") BigDecimal deliveryLongitude,
                                                    @Param("deliveryLatitude") BigDecimal deliveryLatitude,
                                                    @Param("vehicleType") String vehicleType,
                                                    @Param("loadCapacity") BigDecimal loadCapacity,
                                                    @Param("volumeCapacity") BigDecimal volumeCapacity,
                                                    @Param("timeWindow") String timeWindow,
                                                    @Param("radius") BigDecimal radius,
                                                    @Param("limit") Integer limit);

    /**
     * 查询派单统计信息
     *
     * @param dispatchId 派单ID
     * @param startTime 统计开始时间
     * @param endTime 统计结束时间
     * @return 统计信息
     */
    Map<String, Object> selectDispatchStatistics(@Param("dispatchId") Long dispatchId,
                                                @Param("startTime") LocalDateTime startTime,
                                                @Param("endTime") LocalDateTime endTime);

    /**
     * 更新派单状态
     *
     * @param dispatchId 派单ID
     * @param dispatchStatus 派单状态
     * @param updateTime 更新时间
     * @param remark 备注
     * @return 更新行数
     */
    int updateDispatchStatus(@Param("dispatchId") Long dispatchId,
                            @Param("dispatchStatus") Integer dispatchStatus,
                            @Param("updateTime") LocalDateTime updateTime,
                            @Param("remark") String remark);

    /**
     * 更新派单司机信息
     *
     * @param dispatchId 派单ID
     * @param driverCode 司机编号
     * @param driverName 司机姓名
     * @param driverPhone 司机手机号
     * @param vehicleCode 车辆编号
     * @param vehiclePlateNumber 车牌号
     * @param assignTime 分配时间
     * @param updateTime 更新时间
     * @return 更新行数
     */
    int updateDispatchDriver(@Param("dispatchId") Long dispatchId,
                            @Param("driverCode") String driverCode,
                            @Param("driverName") String driverName,
                            @Param("driverPhone") String driverPhone,
                            @Param("vehicleCode") String vehicleCode,
                            @Param("vehiclePlateNumber") String vehiclePlateNumber,
                            @Param("assignTime") LocalDateTime assignTime,
                            @Param("updateTime") LocalDateTime updateTime);

    /**
     * 更新派单匹配得分
     *
     * @param dispatchId 派单ID
     * @param matchScore 匹配得分
     * @param algorithmVersion 算法版本
     * @param updateTime 更新时间
     * @return 更新行数
     */
    int updateDispatchMatchScore(@Param("dispatchId") Long dispatchId,
                                @Param("matchScore") BigDecimal matchScore,
                                @Param("algorithmVersion") String algorithmVersion,
                                @Param("updateTime") LocalDateTime updateTime);

    /**
     * 更新派单时间信息
     *
     * @param dispatchId 派单ID
     * @param acceptTime 接单时间
     * @param pickupTime 取货时间
     * @param deliveryTime 配送时间
     * @param completeTime 完成时间
     * @param updateTime 更新时间
     * @return 更新行数
     */
    int updateDispatchTimeInfo(@Param("dispatchId") Long dispatchId,
                              @Param("acceptTime") LocalDateTime acceptTime,
                              @Param("pickupTime") LocalDateTime pickupTime,
                              @Param("deliveryTime") LocalDateTime deliveryTime,
                              @Param("completeTime") LocalDateTime completeTime,
                              @Param("updateTime") LocalDateTime updateTime);

    /**
     * 更新派单费用信息
     *
     * @param dispatchId 派单ID
     * @param actualDistance 实际距离
     * @param actualDuration 实际时长
     * @param actualCost 实际费用
     * @param updateTime 更新时间
     * @return 更新行数
     */
    int updateDispatchCostInfo(@Param("dispatchId") Long dispatchId,
                              @Param("actualDistance") BigDecimal actualDistance,
                              @Param("actualDuration") Integer actualDuration,
                              @Param("actualCost") BigDecimal actualCost,
                              @Param("updateTime") LocalDateTime updateTime);

    /**
     * 更新派单异常信息
     *
     * @param dispatchId 派单ID
     * @param exceptionType 异常类型
     * @param exceptionReason 异常原因
     * @param exceptionTime 异常时间
     * @param handleStatus 处理状态
     * @param updateTime 更新时间
     * @return 更新行数
     */
    int updateDispatchExceptionInfo(@Param("dispatchId") Long dispatchId,
                                   @Param("exceptionType") String exceptionType,
                                   @Param("exceptionReason") String exceptionReason,
                                   @Param("exceptionTime") LocalDateTime exceptionTime,
                                   @Param("handleStatus") Integer handleStatus,
                                   @Param("updateTime") LocalDateTime updateTime);

    /**
     * 更新派单评价信息
     *
     * @param dispatchId 派单ID
     * @param rating 评分
     * @param comment 评价内容
     * @param ratingTime 评价时间
     * @param updateTime 更新时间
     * @return 更新行数
     */
    int updateDispatchRating(@Param("dispatchId") Long dispatchId,
                            @Param("rating") Integer rating,
                            @Param("comment") String comment,
                            @Param("ratingTime") LocalDateTime ratingTime,
                            @Param("updateTime") LocalDateTime updateTime);

    /**
     * 批量更新派单状态
     *
     * @param dispatchIds 派单ID列表
     * @param dispatchStatus 派单状态
     * @param updateTime 更新时间
     * @return 更新行数
     */
    int batchUpdateDispatchStatus(@Param("dispatchIds") List<Long> dispatchIds,
                                 @Param("dispatchStatus") Integer dispatchStatus,
                                 @Param("updateTime") LocalDateTime updateTime);

    /**
     * 查询派单成功率统计
     *
     * @param startTime 统计开始时间
     * @param endTime 统计结束时间
     * @param dispatchType 派单类型
     * @param dispatchMethod 派单方式
     * @return 成功率统计信息
     */
    Map<String, Object> selectDispatchSuccessRateStatistics(@Param("startTime") LocalDateTime startTime,
                                                           @Param("endTime") LocalDateTime endTime,
                                                           @Param("dispatchType") String dispatchType,
                                                           @Param("dispatchMethod") String dispatchMethod);

    /**
     * 查询派单效率统计
     *
     * @param startTime 统计开始时间
     * @param endTime 统计结束时间
     * @param algorithmVersion 算法版本
     * @return 效率统计信息
     */
    Map<String, Object> selectDispatchEfficiencyStatistics(@Param("startTime") LocalDateTime startTime,
                                                          @Param("endTime") LocalDateTime endTime,
                                                          @Param("algorithmVersion") String algorithmVersion);

    /**
     * 查询派单时间分布统计
     *
     * @param startTime 统计开始时间
     * @param endTime 统计结束时间
     * @return 时间分布统计信息
     */
    List<Map<String, Object>> selectDispatchTimeDistributionStatistics(@Param("startTime") LocalDateTime startTime,
                                                                       @Param("endTime") LocalDateTime endTime);

    /**
     * 查询派单类型分布统计
     *
     * @param startTime 统计开始时间
     * @param endTime 统计结束时间
     * @return 类型分布统计信息
     */
    List<Map<String, Object>> selectDispatchTypeDistributionStatistics(@Param("startTime") LocalDateTime startTime,
                                                                       @Param("endTime") LocalDateTime endTime);

    /**
     * 查询派单地区分布统计
     *
     * @param startTime 统计开始时间
     * @param endTime 统计结束时间
     * @return 地区分布统计信息
     */
    List<Map<String, Object>> selectDispatchRegionDistributionStatistics(@Param("startTime") LocalDateTime startTime,
                                                                         @Param("endTime") LocalDateTime endTime);

    /**
     * 查询派单异常统计
     *
     * @param startTime 统计开始时间
     * @param endTime 统计结束时间
     * @param exceptionType 异常类型
     * @return 异常统计信息
     */
    List<Map<String, Object>> selectDispatchExceptionStatistics(@Param("startTime") LocalDateTime startTime,
                                                               @Param("endTime") LocalDateTime endTime,
                                                               @Param("exceptionType") String exceptionType);

    /**
     * 查询派单评价统计
     *
     * @param startTime 统计开始时间
     * @param endTime 统计结束时间
     * @param driverCode 司机编号
     * @return 评价统计信息
     */
    Map<String, Object> selectDispatchRatingStatistics(@Param("startTime") LocalDateTime startTime,
                                                      @Param("endTime") LocalDateTime endTime,
                                                      @Param("driverCode") String driverCode);

    /**
     * 查询派单算法性能统计
     *
     * @param algorithmVersion 算法版本
     * @param startTime 统计开始时间
     * @param endTime 统计结束时间
     * @return 算法性能统计信息
     */
    Map<String, Object> selectDispatchAlgorithmPerformanceStatistics(@Param("algorithmVersion") String algorithmVersion,
                                                                     @Param("startTime") LocalDateTime startTime,
                                                                     @Param("endTime") LocalDateTime endTime);

    /**
     * 查询派单重试统计
     *
     * @param startTime 统计开始时间
     * @param endTime 统计结束时间
     * @return 重试统计信息
     */
    Map<String, Object> selectDispatchRetryStatistics(@Param("startTime") LocalDateTime startTime,
                                                     @Param("endTime") LocalDateTime endTime);

    /**
     * 查询派单超时统计
     *
     * @param startTime 统计开始时间
     * @param endTime 统计结束时间
     * @return 超时统计信息
     */
    Map<String, Object> selectDispatchTimeoutStatistics(@Param("startTime") LocalDateTime startTime,
                                                       @Param("endTime") LocalDateTime endTime);

    /**
     * 软删除派单信息
     *
     * @param dispatchId 派单ID
     * @param updateTime 更新时间
     * @return 更新行数
     */
    int softDeleteDispatch(@Param("dispatchId") Long dispatchId,
                          @Param("updateTime") LocalDateTime updateTime);

    /**
     * 批量软删除派单信息
     *
     * @param dispatchIds 派单ID列表
     * @param updateTime 更新时间
     * @return 更新行数
     */
    int batchSoftDeleteDispatches(@Param("dispatchIds") List<Long> dispatchIds,
                                 @Param("updateTime") LocalDateTime updateTime);

    /**
     * 恢复已删除的派单信息
     *
     * @param dispatchId 派单ID
     * @param updateTime 更新时间
     * @return 更新行数
     */
    int restoreDispatch(@Param("dispatchId") Long dispatchId,
                       @Param("updateTime") LocalDateTime updateTime);

    /**
     * 查询派单操作日志
     *
     * @param dispatchId 派单ID
     * @param startTime 查询开始时间
     * @param endTime 查询结束时间
     * @param limit 查询数量限制
     * @return 操作日志列表
     */
    List<Map<String, Object>> selectDispatchOperationLogs(@Param("dispatchId") Long dispatchId,
                                                         @Param("startTime") LocalDateTime startTime,
                                                         @Param("endTime") LocalDateTime endTime,
                                                         @Param("limit") Integer limit);
}